User:RossPatterson/Reorganize References.js
Appearance
Code that you insert on this page could contain malicious content capable of compromising your account. If you import a script from another page with "importScript", "mw.loader.load", "iusc", or "lusc", take note that this causes you to dynamically load a remote script, which could be changed by others. Editors are responsible for all edits and actions they perform, including by scripts. User scripts are not centrally supported and may malfunction or become inoperable due to software changes. A guide to help you find broken scripts is available. If you are unsure whether code you are adding to this page is safe, you can ask at the appropriate village pump. This code will be executed when previewing this page. |
Documentation for this user script can be added at User:RossPatterson/Reorganize References. |
/* <nowiki> */
/* Add an editting tab called "ReorgRef" to convert reorganize references */
/*
Simply add ''importScript("User:RossPatterson/Reorganize References.js");'' to your own monobook.js and clear the cache before it will work.
*/
/* Version 1.0 */
var RossPatterson_Reorganize_References = function () {
var _private = {
generatedNameIndex: 0
,
debugLevel: 0
,
debug: function(text) {
if (_private.debugLevel > 0) {
alert(text);
}
}
,
reorgRefs: function (articleText, refs) {
_private.debug("reorgRefs: start");
// Match "<ref>...</ref>", "<ref name=x>...</ref>", etc., but not "<ref name=x/>"
var refPat = new RegExp("(<ref[^/>]*>[^<]*</ref\\s*>)", "gi");
var refElements = (articleText.match(refPat));
_private.debug("reorgRefs: Found " + refElements.length + " references");
for (var i=0; i < refElements.length; i++) {
_private.debug("reorgRefs: i=" + i);
_private.debug("reorgRefs: refElements[" + i + "]=" + refElements[i]);
var name = '';
var originalRef=refElements[i];
var refParms=refElements[i].substr(4, refElements[i].indexOf('>') - 4); // "<ref xxxx>yyy" -> " xxxx"
if (refParms != "" && refParms.search(new RegExp("\\s+name\\s*=", "i")) != -1) {
// Extract the existing "name=x"
name = refParms.replace(new RegExp("\\s+name\\s*=\\s*([^\\s]*)", "i"), '$1');
_private.debug("reorgRefs: found name=" + name);
} else {
_private.debug("reorgRefs: no name=");
// No "name=x", add one
name = _private.chooseUniqueName(refElements[i], articleText);
refElements[i] = "<ref name=" + name + refElements[i].substr(4); // "<ref xxxx>yyy" -> " <ref name=zzz xxxx>yyy"
_private.debug("reorgRefs: modified refElements[" + i + "]=" + refElements[i]);
}
refs.push(refElements[i]);
articleText = articleText.replace(originalRef, "<ref name=" + name + "/>");
}
_private.debug("reorgRefs: end");
return articleText;
}
,
chooseUniqueName: function (refText, articleText) {
_private.debug("chooseUniqueName: start");
var name='';
// Try to use the parameters of {{cite whatever}} to set the reference name
if (refText.search(new RegExp("\\{\\{[Cc]ite")) != -1) {
_private.debug("chooseUniqueName: found {{cite");
// Build an array of parameters by name
var temp = refText.substr(refText.indexOf("|")); // "{{cite whatever |aa=bb |cc=dd}}eee" -> "|aa=bb |cc=dd}}eee"
temp = temp.substr(0, temp.indexOf("}}")); // "|aa=bb |cc=dd}}eee" -> "|aa=bb |cc=dd"
var temp2 = temp.split("|"); // "|aa=bb |cc=dd" -> ["aa=bb", "cc=dd"]
var citeParms = new Array();
for (var i=0; i < temp2.length; i++) {
var temp3 = temp2[i].split("="); // "aa=bb" -> ["aa",bb"]
if ((temp2[i] == "") || (temp3[0] == "")) {
continue;
}
citeParms[_private.trim(temp3[0])] = _private.trim(temp3[1]); // citeParams["aa"] = "bb"
}
// Build the reference name from some of the parameters
if ((citeParms["last1"] != null) && (citeParms["last1"] != "")) {
name = citeParms["last1"]; // Add the last1= value
} else if ((citeParms["last"] != null) && (citeParms["last"] != "")) {
name = citeParms["last"]; // Add the last= value
} else if ((citeParms["author1"] != null) && (citeParms["author1"] != "")) {
name = citeParms["author1"]; // Add the author1= value
} else if ((citeParms["author"] != null) && (citeParms["author"] != "")) {
name = citeParms["author"]; // Add the author= value
} else if ((citeParms["editor1"] != null) && (citeParms["editor1"] != "")) {
name = citeParms["editor1"]; // Add the editor1= value
} else if ((citeParms["editor"] != null) && (citeParms["editor"] != "")) {
name = citeParms["editor"]; // Add the editor= value
} else if ((citeParms["publisher"] != null) && (citeParms["publisher"] != "")) {
name = citeParms["publisher"]; // Add the publisher= value
} else if ((citeParms["title"] != null) && (citeParms["title"] != "")) {
name = citeParms["title"]; // Add the title= value
}
name = name + " ";
if ((citeParms["date"] != null) && (citeParms["date"] != "")) {
name = name + citeParms["date"]; // Add the date= value
} else if ((citeParms["year"] != null) && (citeParms["year"] != "")) {
name = name + citeParms["year"]; // Add the year= value
}
name = name.replace(new RegExp("[\\W]+", "g"), " "); // Replace whitespace, specials, ...
name = (_private.trim(name)).replace(new RegExp("[\\s]+", "g"), "_"); // ... with "_"
_private.debug("chooseUniqueName: name=" + name);
if (articleText.indexOf(name) == -1) {
return '"' + name + '"';
}
_private.debug("chooseUniqueName: name already in use");
}
// Try to use the URL components to set the reference name
if (refText.search(new RegExp("^<ref[^/>]*>\\s*\\[\\s*https?:")) != -1) {
_private.debug("chooseUniqueName: found http:");
var URL = (refText.match(new RegExp("https?:[^\\s]*[^?;<\\]]*")))[0]; // "<ref xx>[http://aaa/bbb ccc]</ref>" -> "http://aaa/bbb ccc"
_private.debug("chooseUniqueName: URL=" + URL);
var host = URL.replace(new RegExp("^https?:\\/\\/([^\\/]*)\\/.*$"), '$1'); // Isolate the hostname/IP addr
_private.debug("chooseUniqueName: host=" + host);
var path = URL.replace(new RegExp("^https?:\\/\\/[^\\/]*\\/([^\\s]*).*$"), '$1'); // Isolate the pathname
_private.debug("chooseUniqueName: path=" + path);
var title = URL.replace(new RegExp("^https?:\\/\\/[^\\/]*\\/[^\\s]*\\s+(.*)$"), '$1'); // Isolate the title
_private.debug("chooseUniqueName: title=" + title);
var file= path.replace(new RegExp("^.*([^\\/]*)$"), '$1'); // Isolate the file name from the pathname
_private.debug("chooseUniqueName: file=" + file);
if (host != "") {
name = host;
}
name = name + " ";
if (title != "") {
name = name + title;
} else if (file != "") {
name = name + file;
} else if (path != "") {
name = name + path;
}
name = name.replace(new RegExp("[\\W]+", "g"), " "); // Replace whitespace, specials, ...
name = (_private.trim(name)).replace(new RegExp("[\\s]+", "g"), "_"); // ... with "_"
_private.debug("chooseUniqueName: name=" + name);
if (articleText.indexOf(name) == -1) {
return '"' + name + '"';
}
_private.debug("chooseUniqueName: name already in use");
}
// Make up a name of our own when all else fails
for (var i=0; i < 20; i++) {
name = '"RRGEN_' + _private.generatedNameIndex++ + '_"';
_private.debug("chooseUniqueName: name=" + name);
if (articleText.indexOf(name) == -1) {
return name;
}
_private.debug("chooseUniqueName: name already in use");
}
alert("chooseUniqueName: Unable to generate a unique name for reference: " + refText);
exit(1);
}
,
addRefs: function (articleText, refs) {
_private.debug("addRefs: start");
var referencesEndTag = new RegExp("(</references[^>]*>)", "i");
var referencesMinTag = new RegExp("<(references)([^\\/>]*)\\/>", "i");
var reflistWithRefs = new RegExp("(\\{\\{[Rr]eflist[^\\}]*\\s*\\|\\s*refs=)");
var reflistNoRefs = new RegExp("(\\{\\{[Rr]eflist[^}]*)\\}\\}");
if (articleText.search(referencesEndTag) != -1) {
// Add our collected refs to the existing <references>...</references>
articleText = articleText.replace(referencesEndTag, refs.join("\n") + "\n$1");
} else if (articleText.search(reflistWithRefs) != -1) {
// Add our collected refs to the existing {{reflist refs=...}}
articleText = articleText.replace(reflistWithRefs, "$1\n" + refs.join("\n") + "\n");
} else if (articleText.search(referencesMinTag) != -1) {
// Expand the references tag and insert our collected refs
articleText = articleText.replace(referencesMinTag, "<$1$2>\n" + refs.join("\n") + "\n</$1>");
} else if (articleText.search(reflistNoRefs) != -1) {
// Expand the {{reflist}} and include our collected refs
articleText = articleText.replace(reflistNoRefs, "$1 |refs=\n" + refs.join("\n") + "\n}}");
} else {
alert("addRefs: Can't find reference list, adding my own!!!!");
articleText += "<references>\n" + refs.join("\n") + "\n</references>";
}
_private.debug("addRefs: end");
return articleText;
}
,
trim: function (input) {
if (input == null) {
return "";
}
var start;
var end;
for (start = 0; start < input.length; start++) {
if (input[start] != " ") {
break;
}
}
for (end = input.length; end >= 0; end--) {
if (input[end] != " ") {
break;
}
}
return input.substr(start, end);
}
}
var _public = {
run: function () {
_private.debug("run: start");
var articleTextField = document.editform.wpTextbox1;
var articleText = articleTextField.value;
var refs = new Array();
articleText = _private.reorgRefs(articleText, refs);
articleTextField.value = _private.addRefs(articleText, refs);
// Add a tag to the summary box
var summaryField = document.editform.wpSummary;
var summary = "Reorganize references";
if (summaryField.value.indexOf(summary) == -1) {
// If the summary contains anything other than a section comment, add a separator
if (summaryField.value.match(/[^\*\/\s][^\/\s]?\s*$/)) {
summaryField.value += "; ";
}
summaryField.value += summary;
}
// Press the "Show changes" button to let the user see the diffs.
document.editform.wpDiff.click()
_private.debug("run: end");
}
,
initialize: function () {
if (document.forms.editform) {
mw.util.addPortletLink('p-cactions', 'javascript:RossPatterson_Reorganize_References.run()',
'RefReorg', 'ca-ref-reorg', 'Reorganize references', '', '');
}
}
}
return _public;
}();
addOnloadHook(RossPatterson_Reorganize_References.initialize);
/* </nowiki> */